/* Universidad del Valle de Guatemala
 * CC2003 - Algoritmos y Estructuras de Datos
 * HOJA DE TRABAJO #5
 * Fecha de Entrega: Jueves 1 de Septiembre de 2011
 */

/**
 * Clase que define las acciones que puede realizar la Cola implementada por medio de una lista circular. 
 * @author José Antonio Bagur - 10275
 */

public class ListaBanco <E> extends AbstractQueue <E> {
    
    /* ATRIBUTOS DE LA CLASE LISTABANCO */
    
    public Node <E> cola;
    
    /* CONSTRUCTOR DE LA CLASE LISTABANCO */
    
    /**
     * Constructor de la Clase ListaBanco, inicializa los atributos de la lista. 
     * @param n número de elementos inicialmente en la lista.
     */
    public ListaBanco(int n) {
        cola = null;
        tamaño = n;
        contador = 0;
    }
    
    /* MÉTODO QUEUE */
    
    /**
     * Método que permite ingresar elementos a la Lista del Banco. 
     * @param E elemento a insertar en la Lista.
     * @throws QueueOverflow 
     */
    public void queue(E elemento) throws QueueOverflow {
        Node <E> temporal  = new Node(elemento);
        
        if (!this.getFull()) {
            if (cola == null) {
                cola = temporal;
                cola.setNext(cola);
            }
            else {
                temporal.setNext(cola.getNext());
                cola.setNext(temporal);
            }
            this.contador++;
        } else {
            throw new QueueOverflow("DESBORDAMIENTO");
        }        
    }
    
    /**
     * Método que permite extraer el primer elemento de la cabeza de la Lista del Banco. 
     * @return E primer elemento de la Lista. 
     * @throws QueueUnderflow 
     */
    public E dequeue() throws QueueUnderflow {
        Node <E> temporal = cola;
        if (!this.getEmpty()) {
            while(temporal.getNext() != cola) 
                temporal = temporal.getNext();
            Node <E> temporal2 = cola;
            
            if (temporal == cola)
                cola = null;
            else {
                temporal.setNext(cola.getNext());
                cola = temporal;
            }
            this.contador--;
            return (E)temporal2.getElement();    
        } else {
             throw new QueueUnderflow("SUBDESBORDAMIENTO");
        }
    }
    
    /**
     * Método que retorna el elemento presente en la cabeza de la Cola implementada por medio de la Lista; no lo extrae de la Cola.
     * @return
     * @throws QueueUnderflow 
     */
    public E peek() throws QueueUnderflow {
        Node <E> temporal = cola;
        
        if (!this.getEmpty()) {
            while (temporal != cola)
                temporal = temporal.getNext();
            return (E)temporal.getElement();
        } else {
            throw new QueueUnderflow("SUBDESBORDAMIENTO");
        }
    }
    
} // FIN DE LA CLASE LISTABANCO
